"""
!/usr/bin/env python
-*- coding: utf-8 -*-
@Author  : MarkJia
@Site    : 
@File    : 31、第三方库：urllib3.py
"""

"""
发送请求：
    内置模块 ： urllib
    第三方库 ： requests urllib3

urllib3 ： 是python客户端 http 协议的客户端
    1、线程安全
    2、连接池管理
    3、客户端 SSL/TLS 验证
    4、支持 HTTP 和 SOCKS 代理
    官方文档： https://urllib3.readthedocs.io/en/stable/

安装 ： pip install urllib3
"""
import json
import urllib3

"""
urllib3 发送 HTTP 请求：
    1、导入 urllib3 模块
    2、创建 PoolManger 实例
    3、调用 request() 方法

"""


def test_http():
    # 创建线程池对象，默认会校验证书
    pm = urllib3.PoolManager()
    # 发送HTTP请求
    res = pm.request(method='GET', url="http://httpbin.org/get")
    # 结果：<class 'urllib3.response.HTTPResponse'>
    print(type(res))
    # 打印响应状态码
    print(res.status)  # 200
    # 打印响应头信息
    print(
        res.headers)  # HTTPHeaderDict({'Date': 'Sat, 04 Jun 2022 10:13:58 GMT', 'Content-Type': 'application/json', 'Content-Length': '278', 'Connection': 'keep-alive', 'Server': 'gunicorn/19.9.0', 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Credentials': 'true'})
    # 打印响应数据  数据为二进制编码格式
    print(
        res.data)  # b'{\n  "args": {}, \n  "headers": {\n  "Accept-Encoding": "identity", \n    "Host": "httpbin.org", \n "User-Agent": "python-urllib3/1.26.9", \n    "X-Amzn-Trace-Id": "Root=1-629b3066-758ce4db02a3cf055565cbab"\n  }, \n  "origin": "111.18.94.186", \n  "url": "http://httpbin.org/get"\n}\n'


# 将二进制转化成字符串
def test_response():
    # 创建线程池对象，默认会校验证书
    pm = urllib3.PoolManager()
    # 发送HTTP请求
    res = pm.request(method='GET', url="http://httpbin.org/ip")
    # 获取二进制形式得响应内容
    raw = res.data
    # 结果：b'{\n  "origin": "111.18.94.186"\n}\n' <class 'bytes'>
    print(raw, type(raw))

    # 使用utf-8：将二进制数据解码成字符串
    content = raw.decode('utf-8')
    # 返回一个json格式文本
    """
    结果： <class 'str'>
    {
      "origin": "111.18.94.186"
    }
     <class 'str'>
    """
    print(content, type(content))

    # 使用json，转化成字典对象，方便断言取值
    obj_data = json.loads(content)
    # 结果 ： {'origin': '111.18.94.186'} <class 'dict'>
    print(obj_data, type(obj_data))
    # 获取的结果是 ： 111.18.94.186
    print(obj_data['origin'])


"""
request请求方法
必填参数：
    method - 请求方式（get/post/put/delete）
    url ：请求地址 : ip 地址 或者 域名
选填参数
    headers: 请求头信息
    fields:  请求体数据
    body：   指定请求体类型
    timeout: 设置超时时间
"""


# 定制请求头
def test_headers():
    pm = urllib3.PoolManager()
    url = 'http:httpbin.org/get'

    # 定制请求头
    headers = {'Hello': 'python'}

    # 发送请求
    resp = pm.request('GET', url, headers=headers)

    # 查看响应数据,转化成字典格式
    connent = json.loads(resp.data.decode('utf-8'))
    print(connent)
    # 查看响应头信息
    print(connent['headers'])


# 定义请求数据
# get请求
def test_quarystr_get():
    pm = urllib3.PoolManager()
    url = 'http:httpbin.org/get'

    # 定制查询字符串
    fields = {'data': 'hello_python'}
    # 发送请求
    resp = pm.request('GET', url, fields=fields)
    # 查看响应数据,转化成字典格式
    connent = json.loads(resp.data.decode('utf-8'))
    print(connent)


# post/put请求
def test_quarystr_post():
    pm = urllib3.PoolManager()
    url = 'http:httpbin.org/post'

    # 从内置库 urllib 库的 parse 模块导入编码方法
    from urllib.parse import urlencode
    encode_str = urlencode({'school': 'hogwarts'})

    # 拼接到url中，发送请求   'http:httpbin.org/post?school=hogwarts'
    resp = pm.request('POST', url=url + '?' + encode_str)

    # 查看响应数据,转化成字典格式
    connent = json.loads(resp.data.decode('utf-8'))
    print(connent)


# 定制请求体类型
# 1、form表单数据   'Content-Type':'multipart/form-data'
# 2、提交json数据    'Content-Type':'application/json'

# form 表单格式数据
def test_form():
    pm = urllib3.PoolManager()
    url = 'http:httpbin.org/post'
    # 定制查询字符串
    fields = {'school': 'hogwarts'}
    # 发送请求
    resp = pm.request('POST', url, fields=fields)
    # 查看响应数据,转化成字典格式
    connent = json.loads(resp.data.decode('utf-8'))
    print(connent)
    print(connent['form'])


# json 格式的请求体
def test_json():
    pm = urllib3.PoolManager()
    url = 'http:httpbin.org/post'

    # 设定请求体数据
    headers = {'Content-Type': 'application/json'}

    # 格式json文本数据
    json_str = json.dumps({'school': 'hogwarts'})

    # 发送请求
    resp = pm.request('POST', url, headers=headers, body=json_str)

    # 查看响应数据,转化成字典格式
    connent = json.loads(resp.data.decode('utf-8'))
    print(connent)


# 定制请求的超时时间
def test_timeout_4s():
    pm = urllib3.PoolManager()
    # 访问该 url ，服务器会在 3s 后响应
    url = 'http://httpbin.org/delay/3'

    # 设置超时时间   是一个浮点数
    resp = pm.request('GET', url=url, timeout=4.0)
    print(resp.stauts)
    # 断言响应状态码是否等于200
    assert resp.stauts == 200


"""
urllib3发送 https 请求
    HTTPS 请求默认需要校验证书
    PoolManager 的 cert_reqs 参数：
        需要校验证书设置：CERT_REQUIRED    
        取消证书设置：CERT_NONE
"""


def test_https():
    url = 'https://httpbin.ceshiren.com/get'

    # 创建不校验证书的连接池对象
    pm_https = urllib3.PoolManager(cert_reqs='CERT_NONE')

    # 发送https请求
    resp = pm_https.request('GET', url)

    # 打印响应结果
    connent = json.dumps(resp.data.decode('utf-8'))
    # {\n  \"args\": {}, \n  \"headers\": {\n    \"Accept-Encoding\": \"identity\", \n    \"Host\": \"httpbin.ceshiren.com\", \n    \"User-Agent\": \"python-urllib3/1.26.9\", \n    \"X-Forwarded-Host\": \"httpbin.ceshiren.com\", \n    \"X-Forwarded-Scheme\": \"https\", \n    \"X-Scheme\": \"https\"\n  }, \n  \"origin\": \"172.17.56.110\", \n  \"url\": \"https://httpbin.ceshiren.com/get\"\n}\n"
    print(connent)
